 package com.ihome.android.util;

import java.io.File;
import java.io.FileOutputStream;
import java.lang.ref.SoftReference;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;

import com.ihome.android.common.ConfigUtil;
import com.ihome.android.util.log.LogUtil;

public class ImageLoader {
	private static String						TAG						= ImageLoader.class.getSimpleName();
	public Map<String, SoftReference<Drawable>>	imageCache				= new HashMap<String, SoftReference<Drawable>>();
	private ExecutorService						executorService			= Executors.newFixedThreadPool(5);					// 固定五个线程来执行任务
	private final Handler						handler					= new Handler();
	private Context								context;
	private String								diskurl;
	private CompressFormat						compressedImageFormat	= CompressFormat.PNG;
	private int									cachedImageQuality		= 100;

	public ImageLoader(Context context) {
		this.context = context;
		this.diskurl = ConfigUtil.IMG_PATH;
		new File(diskurl).mkdirs();
	}

	private File getImageFile(String imageUrl) {
		String fileName = Integer.toHexString(imageUrl.hashCode()) + "." + compressedImageFormat.name();
		return new File(this.diskurl + "/" + fileName);
	}

	private String getFullPath(String imageUrl) {
		return this.diskurl + "/" + Integer.toHexString(imageUrl.hashCode()) + "." + compressedImageFormat.name();
	}

	/**
	 * 
	 * @param imageUrl
	 *            图像url地址
	 * @param callback
	 *            回调接口
	 * @return 返回内存中缓存的图像，第一次加载返回null
	 */
	public Drawable loadDrawable(final String imageUrl, final ImageCallback callback) {
		if (imageCache.containsKey(imageUrl)) {
			SoftReference<Drawable> softReference = imageCache.get(imageUrl);
			if (softReference.get() != null) {
				//LogUtil.v(TAG "loadDrawable >> From softReference");
				return softReference.get();
			}
		}

		File imageFile = getImageFile(imageUrl);
		if (imageFile.exists() && imageFile.length() > 0) {
			String path = getFullPath(imageUrl);
			Drawable draw = Drawable.createFromPath(path);
			imageCache.put(imageUrl, new SoftReference<Drawable>(draw));
			//LogUtil.v(TAG "loadDrawable >> From ImageCache");
			return draw;
		}

		LogUtil.v(TAG, "loadDrawable >> From Intenet");
		executorService.submit(new LoadImageRunnable(imageUrl, callback));
		return null;
	}
	
	public Drawable loadImageFromDisk(String picpath){
		Drawable draw = null;
		if (imageCache.containsKey(picpath)) {
			SoftReference<Drawable> softReference = imageCache.get(picpath);
			if (softReference.get() != null) {
				LogUtil.v(TAG, "loadImageFromDisk >> From softReference");
				draw = softReference.get();
			}
			else {
				LogUtil.v(TAG, "loadImageFromDisk >> BitmapFactory.decodeFile");
				draw = Drawable.createFromPath(picpath);
				imageCache.put(picpath, new SoftReference<Drawable>(draw));
			}
		}
		else {
			LogUtil.v(TAG, "loadImageFromDisk >> BitmapFactory.decodeFile");
			Bitmap bitmap = ImageHelper.decodeFile(new File(picpath));
			draw = new BitmapDrawable(bitmap);
			imageCache.put(picpath, new SoftReference<Drawable>(draw));
		}
		
		return draw;
	}

	/**
	 * 根据图片url从网络加载数据
	 * 
	 * @param imageUrl
	 * @return
	 */
	protected BitmapDrawable loadImageFromUrl(String imageUrl) {
		HttpURLConnection http = null;
		try {
//			http = Http.getInstance(context).getHttpURLConnection(imageUrl, null);
//			if (http.getResponseCode() == HttpStatus.SC_OK) {
//				return (BitmapDrawable) Drawable.createFromStream(http.getInputStream(), "image.png");
//			}
//			else {
				LogUtil.v(TAG, "Turn to URL.openStream()");
				return (BitmapDrawable) Drawable.createFromStream(new URL(imageUrl).openStream(), "image.png");
//			}
			
		} catch (Exception e) {
			LogUtil.e(TAG, " Exception >> " + e.toString());
		} finally{
			if (http != null)
				http.disconnect();
		}
		return null;
	}

	public interface ImageCallback {
		public void imageLoaded(Drawable imageDrawable);
	}

	private void saveImage2Cache(BitmapDrawable drawable, String imageUrl) {
		try {
			File imageFile = getImageFile(imageUrl.toString());
			imageFile.createNewFile();
			FileOutputStream ostream = new FileOutputStream(imageFile);
			drawable.getBitmap().compress(compressedImageFormat, cachedImageQuality, ostream);
			ostream.close();
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}

	private class LoadImageRunnable implements Runnable {
		String			imageUrl;
		ImageCallback	callback;

		public LoadImageRunnable(final String imageUrl, final ImageCallback callback) {
			this.imageUrl = imageUrl;
			this.callback = callback;
		}

		@Override
		public void run() {
			try {
				final BitmapDrawable drawable = loadImageFromUrl(imageUrl);
				if(drawable == null){
					LogUtil.e(TAG, "LoadImageRunnable >> drawable = NULL");
					return;
				}
				imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
				saveImage2Cache(drawable, imageUrl);
				handler.post(new Runnable() {
					public void run() {
						LogUtil.d(TAG, "loadDrawable >> post");
						callback.imageLoaded(drawable);
					}
				});
			} catch (Exception e) {
				LogUtil.e(TAG, " Exception >> " + e.toString());
			}
		}
	}
}
